using System;
using System.Collections.Generic;
using System.Text;

namespace WOWEquipOptimizer.Hunter
{
    class Marksman : Character
    {
        public Marksman()
            : base()
        {
            AllowDualWield = true;
            AllowTwoHand = true;
            m_Base = new List<Attribute>();
            m_Base.Add(new Attribute(AttributeName.Health, 3600));
            m_Base.Add(new Attribute(AttributeName.Mana, 3100));
            m_Base.Add(new Attribute(AttributeName.Stamina, 110));
            m_Base.Add(new Attribute(AttributeName.Spirit, 86));
            m_Base.Add(new Attribute(AttributeName.Intellect, 74));
            m_Base.Add(new Attribute(AttributeName.Strength, 67));
            m_Base.Add(new Attribute(AttributeName.AttackPower, 130));
            m_Base.Add(new Attribute(AttributeName.CritRating, 0.17f * CritRating));
            m_Base.Add(new Attribute(AttributeName.Agility, 148));
            // talent
            m_Base.Add(new Attribute(AttributeName.CritRating, 5 * CritRating));
            m_Base.Add(new Attribute(AttributeName.AttackPower, 110));
            m_Base.Add(new Attribute(AttributeName.AttackPower, 155));
            foreach (Attribute attr in m_Base)
            {
                handleAttribute(attr);
            }
            Buff bow = new Buff("Blessing of Wisdom", new List<Attribute>());
            bow.Attributes.Add(new Attribute(AttributeName.MP5, 41 * 1.2f));
            Buffs.Add(bow);
            Buff mstream = new Buff("Manastream Totem", new List<Attribute>());
            mstream.Attributes.Add(new Attribute(AttributeName.MP5, 12 * 2.5f));
            Buffs.Add(mstream);
            Buff bom = new Buff("Blessing of Might", new List<Attribute>());
            bom.Attributes.Add(new Attribute(AttributeName.AttackPower, 220));
            Buffs.Add(bom);
            Buff relassault = new Buff("Flask of Relentless Assault", new List<Attribute>());
            relassault.Attributes.Add(new Attribute(AttributeName.AttackPower, 120));
            Buffs.Add(relassault);
            Buff majagi = new Buff("Elixir of Major Agility", new List<Attribute>());
            majagi.Attributes.Add(new Attribute(AttributeName.Agility, 35));
            majagi.Attributes.Add(new Attribute(AttributeName.CritRating, 20));
            majagi.Enabled = false;
            Buffs.Add(majagi);
            Buff roastcleft = new Buff("Roasted Clefthoof", new List<Attribute>());
            roastcleft.Attributes.Add(new Attribute(AttributeName.Strength, 20));
            roastcleft.Attributes.Add(new Attribute(AttributeName.Spirit, 20));
            Buffs.Add(roastcleft);
            Buff mudfish = new Buff("Grilled Mudfish", new List<Attribute>());
            mudfish.Attributes.Add(new Attribute(AttributeName.Agility, 20));
            mudfish.Attributes.Add(new Attribute(AttributeName.Spirit, 20));
            mudfish.Enabled = false;
            Buffs.Add(mudfish);
            Buff manapotions = new Buff("Superior Mana Potions", new List<Attribute>());
            manapotions.Attributes.Add(new Attribute(AttributeName.MP5, 2400 / 24));
            Buffs.Add(manapotions);
            Buff goa = new Buff("Grace of Air", new List<Attribute>());
            goa.Attributes.Add(new Attribute(AttributeName.Strength, 77 * 1.15f));
            goa.Enabled = true;
            Buffs.Add(goa);
        }
        public override void evaluateItem(Item item, int slot)
        {
            base.evaluateItem(item, slot);
            if (item.GetType() == typeof(Weapon) && (slot == (int)Enum.Parse(typeof(SlotName), "Ranged", true)))
            {
                m_Equip[AttributeName.MHWDPS] = (item as Weapon).DPS;
                m_Equip[AttributeName.MHWS] = (item as Weapon).Speed;
            }
            if (item.WeaponSkills.Count > 0)
            {
                m_WeaponSkills.AddRange(item.WeaponSkills);
            }
        }
        // WDPS, WS, Crit,Hit, AP, Mana,MP5, health
        public override void handleAttribute(Attribute attr)
        {
            switch (attr.Type)
            {
                case AttributeName.Intellect:
                    m_Equip[AttributeName.Mana] += attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f) * 15 * 1.06f;
                    m_Equip[AttributeName.MP5] += attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f) * 0.45f;
                    break;
                case AttributeName.Agility:
                    m_Equip[AttributeName.CritRating] += 1.02f * (attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f) / 40f) * CritRating;
                    m_Equip[AttributeName.AttackPower] += 1.02f * attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f) * 1.1f;
                    break;
                case AttributeName.AttackPower:
                    m_Equip[attr.Type] += attr.Value * 1.1f;
                    break;
                default:
                    base.handleAttribute(attr);
                    break;
            }
        }
        // WDPS, WS, Crit,Hit, AP, Mana,MP5, health
        // rotation 3 autoshots and 3 stdyshots, 1 arcane
        public override float evaluateTF()
        {
            float runtime = 600;
            float wdps = m_Equip[AttributeName.MHWDPS];
            float ws = m_Equip[AttributeName.MHWS];
            float crit = m_Equip[AttributeName.CritRating] / CritRating;
            float hit = m_Equip[AttributeName.HitRating] / HitRating;
            float ap = m_Equip[AttributeName.AttackPower];
            float mana = m_Equip[AttributeName.Mana];
            float mp5 = m_Equip[AttributeName.MP5];
            hit = (float)Math.Min(100 - 5 - 3.0f - 0.6f + hit, 100);
            float projectiledps = 53f;
            float wshaste = ws / 1.15f;
            float autoshotdps = (wdps + ap / 14f + projectiledps) * Character.Armor;
            float autoshotdmg = autoshotdps * ws;
            float arcaneshotdamage = (ap * 0.2f + 273);
            float arcaneshotmana = 230 * 0.9f;
            float steadyshotdamage = (150 + wdps * 2.8f + 0.2f * ap) * Character.Armor;
            //float steadyshotdamage = (150 + 0.3f * ap) * Character.Armor;
            float steadyshotcasttime = 1.5f / 1.15f;
            wshaste = Math.Max(wshaste, steadyshotcasttime + 0.5f + 0.2f);
            float steadyshotcost = 110 * 0.9f;
            float autoshotcount = runtime / wshaste;
            float manafull = mana + mp5 / 5f * runtime;
            float steadyshotcount = Math.Min(manafull / steadyshotcost, autoshotcount);
            float arcaneshotcount = Math.Min((manafull - steadyshotcount * steadyshotcost) / arcaneshotmana, runtime / 6f);
            float finaldmg = (hit / 100f) * 1.05f * (1 + (crit / 100 * 1.3f)) * (steadyshotcount * steadyshotdamage + autoshotcount * autoshotdmg + arcaneshotcount * arcaneshotdamage);
            float finaldps = finaldmg / runtime;
            return CondFactor * finaldps;
        }
        public override List<Item> filterEquip(List<Item> input)
        {
            input = base.filterEquip(input);
            List<Item> retval = new List<Item>();
            foreach (Item item in input)
            {
                if ((item.AllowableClasses & CharacterClass.Hunter) == 0) continue;
                if (item.GetType() == typeof(Weapon))
                {
                    Weapon weapon = (Weapon)item;
                    if (weapon.WeaponSlot != WeaponSlot.Ranged)
                    {
                        if (weapon.Type == WeaponType.Mace) continue;
                    }
                    else if (weapon.WeaponSlot == WeaponSlot.Ranged)
                    {
                        if (!(weapon.Type == WeaponType.Gun || weapon.Type == WeaponType.Bow || weapon.Type == WeaponType.Crossbow)) continue;
                        
                    }
                }
                else if (item.GetType() == typeof(Armor))
                {
                    Armor armor = (Armor)item;
                    if ((armor.Type & ArmorProficiency.Mail) == 0) continue;
                }
                if (SetBlacklist.Contains(item.Set.Name)) continue;
                if (ItemBlacklist.Contains(item.Name)) continue;
                bool bad = false;
                foreach (Attribute attr in item.Attributes)
                {
                    switch (attr.Type)
                    {
                        case AttributeName.SpellDamage:
                        case AttributeName.HitSpellRating:
                        case AttributeName.CritSpellRating:
                        case AttributeName.Healing:
                            {
                                bad = true;
                                break;
                            }
                        default:
                            break;
                    }
                }
                if (!bad)
                {
                    retval.Add(item);
                }
            }
            return handleWhiteList(retval);
        }
        public override bool evaluateBuild(int[] build)
        {
            if (build[1] >= 41)
            {
                return true;
            }
            else return false;
        }
        public override string[] getAttributes()
        {
            return new string[] { "WDPS", "WS", "CritRating", "HitRating", "Attackpower","Mana", "MP5", "Health" };
        }
        public override int getAttributesStart()
        {
            return 2;
        }
        public override string targetValue()
        {
            return "DPS";
        }
    }
}

